package com.xbongbong.saas.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasProcessDataEntity;
import com.xbongbong.paas.domain.entity.ext.ConditionsEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.elasticsearch.pojo.XbbAggregatedPage;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.help.UserHelp;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasProcessDataModel;
import com.xbongbong.paas.pojo.ButtonPojo;
import com.xbongbong.paas.pojo.dto.UserAndDepartmentGetDTO;
import com.xbongbong.paas.pojo.vo.FormDataRepeatVO;
import com.xbongbong.paas.service.PaasFormService;
import com.xbongbong.paas.service.impl.PaasFormServiceImpl;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.common.pojo.ClueCheckRepeatPojo;
import com.xbongbong.pro.common.pojo.CustomerCheckRepeatPojo;
import com.xbongbong.pro.common.pojo.dto.CheckRepeatDTO;
import com.xbongbong.pro.common.pojo.dto.CustomerCheckRepeatDTO;
import com.xbongbong.pro.common.pojo.dto.RepeatCommonConditionDTO;
import com.xbongbong.pro.common.pojo.vo.CheckRepeatVO;
import com.xbongbong.pro.common.pojo.vo.ClueCheckRepeatVO;
import com.xbongbong.pro.common.pojo.vo.CustomerCheckRepeatVO;
import com.xbongbong.pro.constant.CommonConstant;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.message.constant.WorkOrderPushConstant;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.PublicGroupEntity;
import com.xbongbong.saas.enums.CheckRepeatObjEnum;
import com.xbongbong.saas.enums.CheckRepeatRuleEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.BomBillEnum;
import com.xbongbong.saas.enums.business.ClueEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.dictionary.ClueStatusEnum;
import com.xbongbong.saas.enums.dictionary.DictionaryEnum;
import com.xbongbong.saas.model.DataDictionaryModel;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.model.PublicGroupModel;
import com.xbongbong.saas.service.BomBillService;
import com.xbongbong.saas.service.ClueService;
import com.xbongbong.saas.service.CommonService;
import com.xbongbong.saas.service.ContractService;
import com.xbongbong.saas.service.CustomerService;
import com.xbongbong.saas.service.PublicGroupService;
import com.xbongbong.saas.service.UserTeamService;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.UserModel;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static com.xbongbong.paas.elasticsearch.constant.EsNormalConstant.MINI_MUM_SHOULD_MATCH;
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * @author feng.zheng
 * @version v1.0
 * @date 2019/1/31 16:05
 * @since v1.0
 */
@Service("commonService")
public class CommonServiceImpl implements CommonService {
    private static final Logger LOG = LoggerFactory.getLogger(PaasFormServiceImpl.class);
    @Resource
    private BomBillService bomBillService;
    @Resource
    private CustomerService customerService;
    @Resource
    private ContractService contractService;
    @Resource
    private DataDictionaryModel dataDictionaryModel;
    @Resource
    private PaasFormService paasFormService;
    @Resource
    private UserTeamService userTeamService;
    @Resource
    private PaasProcessDataModel paasProcessDataModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private UserModel userModel;
    @Resource
    private PublicGroupService publicGroupService;
    @Resource
    private EsHelper esHelper;
    @Resource
    private PublicGroupModel publicGroupModel;
    @Resource
    private UserHelp userHelp;
    @Resource
    private ClueService clueService;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private IndexTypeModel indexTypeModel;

    /**
     * 公用查重方法(phone,customerName,contractName,finishedProductVersion)
     *
     * @param checkRepeatDTO 查重入参
     * @return 重复数据
     * @author feng.zheng
     * @date 2019/1/31 16:02
     */
    @Override
    public CheckRepeatVO checkRepeat(CheckRepeatDTO checkRepeatDTO) throws XbbException {
        CheckRepeatVO checkRepeatVO = new CheckRepeatVO();
        Integer checkObj = checkRepeatDTO.getCheckObj();
        JSONObject checkConditionObj = checkRepeatDTO.getCheckCondition();
        CheckRepeatObjEnum checkRepeatObjEnum = CheckRepeatObjEnum.getByCode(checkObj);
        if (checkRepeatObjEnum == null) {
            return checkRepeatVO;
        }
        RepeatCommonConditionDTO repeatCommonConditionDTO = new RepeatCommonConditionDTO();
        BeanUtil.copyProperties(checkRepeatDTO, repeatCommonConditionDTO);
        Integer isRepeat = 0;
        List<String> repeatDataList = new ArrayList<>();
        FormDataRepeatVO formDataRepeatVO;
        String checkRepeatData = "";
        switch (checkRepeatObjEnum) {
            case FINISHED_PRODUCT_VERSION:
                checkRepeatData = checkConditionObj.getString("finishedProductVersion").trim();
                if (StringUtil.isEmpty(checkRepeatData)) {
                    break;
                }
                Long bomId = Long.valueOf(Objects.toString(checkConditionObj.get("bomId"), "0"));
                Long productId = Long.valueOf(Objects.toString(checkConditionObj.get("productId"), "0"));
                formDataRepeatVO = bomBillService.checkRepeatForBomVersion(repeatCommonConditionDTO, checkRepeatData, bomId, productId, false);
                repeatDataList = returnRepeatList(formDataRepeatVO, bomId, CheckRepeatObjEnum.FINISHED_PRODUCT_VERSION);
                checkRepeatVO.setRepeatDataList(repeatDataList);
                break;
            case CUSTOMER_NAME:
                UserVO userVO = checkRepeatDTO.getLoginUser();
                if (!userVO.isAdminOrBoss() && !userVO.getPermSet().contains(ProPermissionAliasEnum.CUSTOMER_DUPLICATE.getAlias())) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050, String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.CUSTOMER_DUPLICATE.getMemo()));
                }
                checkRepeatData = checkConditionObj.getString("customerName");
                Long customerId = checkConditionObj.getLong("customerId");
                formDataRepeatVO = customerService.checkRepeatForCustomerName(repeatCommonConditionDTO, checkRepeatData);
                repeatDataList = returnRepeatList(formDataRepeatVO, customerId, CheckRepeatObjEnum.CUSTOMER_NAME);
                break;
            case CONTRACT_NAME:
                checkRepeatData = checkConditionObj.getString("contractName");
                Long contractId = checkConditionObj.getLong("contractId");
                formDataRepeatVO = contractService.checkRepeatForContractName(repeatCommonConditionDTO, checkRepeatData);
                repeatDataList = returnRepeatList(formDataRepeatVO, contractId, CheckRepeatObjEnum.CONTRACT_NAME);
                break;
            default:
                break;
        }
        for (String repeatData : repeatDataList) {
            if (Objects.equals(checkRepeatData, repeatData)) {
                isRepeat = 1;
                break;
            }
        }
        checkRepeatVO.setRepeatDataList(repeatDataList);
        checkRepeatVO.setIsRepeat(isRepeat);
        return checkRepeatVO;
    }

    /**
     * 返回查重模糊查询的
     *
     * @param formDataRepeatVO 查重返回的list
     * @param dataId           数据id
     * @return 查重返回的对象集合
     * @author feng.zheng
     * @date 2019/2/20 14:38
     */
    private List<String> returnRepeatList(FormDataRepeatVO formDataRepeatVO, Long dataId, CheckRepeatObjEnum checkRepeatObjEnum) throws XbbException {
        if (Objects.isNull(formDataRepeatVO)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.REPEAT_DATA_FAILED);
        }
        List<PaasFormDataEntityExt> formDataList = formDataRepeatVO.getFormDataList();
        if (Objects.isNull(formDataList)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        List<PaasFormDataEntityExt> formDataEsEntityList = new ArrayList<>(formDataList);
        List<String> repeatList = new ArrayList<>();
        Iterator<PaasFormDataEntityExt> it = formDataEsEntityList.iterator();
        while (it.hasNext()) {
            PaasFormDataEntityExt paasFormDataEsEntity = it.next();
            JSONObject data = paasFormDataEsEntity.getData();
            if (Objects.equals(paasFormDataEsEntity.getDataId(), dataId)) {
                it.remove();
                break;
            }
            switch (checkRepeatObjEnum) {
                case FINISHED_PRODUCT_VERSION:
                    String version = FastJsonHelper.getStringFromFormData(data, BomBillEnum.VERSION.getAttr());
                    repeatList.add(version);
                    break;
                case CUSTOMER_NAME:
                    String name = FastJsonHelper.getStringFromFormData(data, CustomerManagementEnum.NAME.getAttr());
                    repeatList.add(name);
                    break;
                case PHONE:
                    JSONArray phone = FastJsonHelper.getJsonArrFromFormData(data, CustomerManagementEnum.PHONE.getAttr());
                    for (Object obj : phone) {
                        JSONObject jsonObject = (JSONObject) obj;
                        repeatList.add(jsonObject.getString("text_2"));
                    }
                    break;
                case CONTRACT_NAME:
                    String contractName = FastJsonHelper.getStringFromFormData(data, ContractEnum.NAME.getAttr());
                    repeatList.add(contractName);
                    break;
                default:
                    break;
            }
        }
        return repeatList;
    }

    @Override
    public CustomerCheckRepeatVO customerCheckRepeat(CustomerCheckRepeatDTO customerCheckRepeatDTO) throws XbbException {
        String corpid = customerCheckRepeatDTO.getCorpid();
        String userId = customerCheckRepeatDTO.getUserId();
        // 获取当前用户的权限
        UserVO loginUser = customerCheckRepeatDTO.getLoginUser();
        Set<String> permSet = loginUser.getPermSet();
        // 是否开启了工作流
        boolean isOpenWorkflow = commonHelp.isOpenWorkFlow(corpid);
        customerCheckRepeatDTO.setIsOpenWorkflow(isOpenWorkflow);
        XbbAggregatedPage<PaasFormDataEntityExt> esEntities = customerService.getDuplicateCustomer(customerCheckRepeatDTO);
        List<CustomerCheckRepeatPojo> list = new ArrayList<>();
        Map<String, String> customerStatusMap = dataDictionaryModel.getDictionaryMap(DictionaryEnum.CUSTOMER_STATUS, corpid, null);
        Map<Long, String> formName = paasFormService.getNameMap(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
        List<Long> customerIdIn = new ArrayList<>();
        // 客户-表单映射关系
        Map<Long, Long> customerFormMap = new HashMap<>();
        for (PaasFormDataEntityExt entity : esEntities.getContent()) {
            customerIdIn.add(entity.getDataId());
            customerFormMap.put(entity.getDataId(), entity.getFormId());
        }
        //获取在公海分组中客户id
        UserAndDepartmentGetDTO userAndDepartmentGetDTO = new UserAndDepartmentGetDTO();
        BeanUtil.copyProperties(customerCheckRepeatDTO, userAndDepartmentGetDTO);
        Map<String, UserEntity> userEntityMap = userHelp.getUserMap(userAndDepartmentGetDTO);
        List<Long> customerIdInGroup = getCustomerIdInGroup(customerCheckRepeatDTO, customerIdIn, customerFormMap);
        Map<Long, List<String>> mainUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, List<String>> coUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        userTeamService.getUserIdMap(customerIdIn, corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), false, mainUserMap, coUserMap);
        // 这里海镔留下了一个坑，针对审批中的数据，这里写死只能通过客户名称查重，即联系方式查重无效（海镔理由是数据库审批数据联系方式查不动）
        // 以上，在客户电话关闭的情况下，审批数据暂时不考虑处理。有利
        List<PaasProcessDataEntity> paasProcessDataEntityList = new ArrayList<>();
        if (!isOpenWorkflow) {
            // 没有开启工作流的时候，需要在流程数据表查询审批中的数据
            paasProcessDataEntityList = paasProcessDataModel.getInApprovalDataByLikeCondition(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), CustomerManagementEnum.NAME.getAttr(), customerCheckRepeatDTO.getNameLike(), corpid, null);
        }
        boolean grabPermission = true;
        if (!permSet.contains(ProPermissionAliasEnum.CUSTOMER_GAIN.getAlias())) {
            grabPermission = false;
        }
        // 查询关闭联系电话的表单
        Map<Long, Integer> openPhoneMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("corpid", corpid);
        map.put("del", DelEnum.NORMAL.getDel());
        map.put("saasMark", BasicConstant.ONE);
        map.put("businessType", XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
        List<PaasFormExplainEntity> paasFormEntityExtList = paasFormExplainModel.list(map);
        for (PaasFormExplainEntity item : paasFormEntityExtList) {
            if (Objects.nonNull(item) && Objects.equals(item.getDel(), DelEnum.NORMAL.getDel())) {
                String explains = item.getExplains();
                if (Objects.nonNull(explains)) {
                    Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(explains, null);
                    if (explainMap != null) {
                        FieldAttrEntity fieldAttrEntity = explainMap.get(CustomerManagementEnum.PHONE.getAttr());
                        openPhoneMap.put(item.getFormId(), BasicConstant.ONE);
                        if (Objects.nonNull(fieldAttrEntity) && (Objects.equals(fieldAttrEntity.getVisible(), BasicConstant.ZERO) || Objects.equals(fieldAttrEntity.getIsOpen(), BasicConstant.ZERO))) {
                            // 只要有一个客户表单模版电话字段不可见，就去除电话字段模糊搜索
                            openPhoneMap.put(item.getFormId(), BasicConstant.ZERO);
                        }
                    }
                }
            }
        }

        for (PaasFormDataEntityExt entity : esEntities.getContent()) {
            // 当客户是电话查重且该表单电话字段关闭，直接过滤数据
            if (Objects.equals(customerCheckRepeatDTO.getRule(), CheckRepeatRuleEnum.PHONE.getCode()) &&
                    Objects.equals(openPhoneMap.get(entity.getFormId()), BasicConstant.ZERO)) {
                continue;
            }
            JSONObject data = entity.getData();
            CustomerCheckRepeatPojo customerCheckRepeatPojo = new CustomerCheckRepeatPojo();
            customerCheckRepeatPojo.setId(entity.getDataId());
            customerCheckRepeatPojo.setAddTime(DateTimeUtil.getStringEpochSecond(entity.getAddTime()));
            customerCheckRepeatPojo.setName(data.getString(CustomerManagementEnum.NAME.getAttr()));
            customerCheckRepeatPojo.setIsArchived(Objects.equals(data.getInteger(CustomerManagementEnum.IS_ARCHIVED.getAttr()), 1) ? I18nMessageUtil.getMessage(CommonConstant.YES) : I18nMessageUtil.getMessage(CommonConstant.NO));
            customerCheckRepeatPojo.setPosition(getCustomerPostion(entity));
            customerCheckRepeatPojo.setCustomerStatus(customerStatusMap.getOrDefault(data.getString(CustomerManagementEnum.TYPE.getAttr()), I18nMessageUtil.getMessage(I18nStringConstant.NOT_SET_UP)));
            Boolean grab = true;
            Boolean addTeam = true;
            List<String> mainUserIdList = mainUserMap.getOrDefault(entity.getDataId(), new ArrayList<>());
            List<String> coUserIdList = coUserMap.getOrDefault(entity.getDataId(), new ArrayList<>());
            if (Objects.equals(entity.getDel(), DelEnum.DELETE.getDel())) {
                grab = false;
                addTeam = false;
            } else if (Objects.equals(data.getInteger(CustomerManagementEnum.IS_PUBLIC.getAttr()), 1)) {
                addTeam = false;
            } else if (mainUserIdList.contains(userId) || coUserIdList.contains(userId)) {
                grab = false;
                addTeam = false;
            } else {
                grab = false;
            }
            //没有公海分组权限的客户
            if (!customerIdInGroup.contains(entity.getDataId())) {
                grab = false;
                addTeam = false;
            }
            // 判断有无 "查重-加入团队" 权限
            if (!permSet.contains(ProPermissionAliasEnum.CUSTOMER_REPEAT_JOIN_TEAM.getAlias())) {
                addTeam = false;
            }
            // 判断捞取权限
            if (!grabPermission) {
                grab = false;
            }
            if (grab) {
                ButtonPojo buttonPojo = new ButtonPojo();
                buttonPojo.setAttr("grab");
                buttonPojo.setValue(I18nMessageUtil.getMessage(I18nStringConstant.GRAB));
                customerCheckRepeatPojo.setOption(Collections.singletonList(buttonPojo));
                customerCheckRepeatPojo.setIsGrab(true);
            }
            if (addTeam) {
                ButtonPojo buttonPojo = new ButtonPojo();
                buttonPojo.setAttr("addTeam");
                buttonPojo.setValue(I18nMessageUtil.getMessage(WorkOrderPushConstant.WORK_ORDER_TEAM_ADD_TITLE));
                customerCheckRepeatPojo.setOption(Collections.singletonList(buttonPojo));
                customerCheckRepeatPojo.setIsAddTeam(true);
            }
            customerCheckRepeatPojo.setFormName(formName.get(entity.getFormId()));
            StringBuilder stringBuilder = new StringBuilder();
            for (String mainUserId : mainUserIdList) {
                UserEntity userEntity = userEntityMap.get(mainUserId);
                if (Objects.isNull(userEntity)) {
                    continue;
                }
                StringUtil.stringBuilderAppendSuffix(stringBuilder, ",", userEntity.getName());
            }
            customerCheckRepeatPojo.setMainUser(stringBuilder.toString());
            list.add(customerCheckRepeatPojo);
        }
        for (PaasProcessDataEntity entity : paasProcessDataEntityList) {
            JSONObject data = JSONObject.parseObject(entity.getData());
            CustomerCheckRepeatPojo customerCheckRepeatPojo = new CustomerCheckRepeatPojo();
            customerCheckRepeatPojo.setId(entity.getTaskId());
            customerCheckRepeatPojo.setAddTime(DateTimeUtil.getStringEpochSecond(entity.getAddTime()));
            customerCheckRepeatPojo.setName(data.getString(CustomerManagementEnum.NAME.getAttr()));
            customerCheckRepeatPojo.setIsArchived(Objects.equals(data.getInteger(CustomerManagementEnum.IS_ARCHIVED.getAttr()), 1) ? I18nMessageUtil.getMessage(CommonConstant.YES) : I18nMessageUtil.getMessage(CommonConstant.NO));
            customerCheckRepeatPojo.setPosition(I18nMessageUtil.getMessage(I18nStringConstant.APPROVAL_LIST));
            customerCheckRepeatPojo.setCustomerStatus(customerStatusMap.getOrDefault(data.getString(CustomerManagementEnum.TYPE.getAttr()), I18nMessageUtil.getMessage(I18nStringConstant.NOT_SET_UP)));
            customerCheckRepeatPojo.setFormName(formName.get(entity.getFormId()));
            UserEntity userEntity = userModel.getByKey(entity.getCreatorId(), corpid);
            if (Objects.nonNull(userEntity)) {
                customerCheckRepeatPojo.setMainUser(userEntity.getName());
            }
            if (Objects.equals(customerCheckRepeatDTO.getRule(), CheckRepeatRuleEnum.NAME.getCode()) && Objects.equals(customerCheckRepeatDTO.getNameLike(), data.getString(CustomerManagementEnum.NAME.getAttr()))) {
                list.add(0, customerCheckRepeatPojo);
            } else {
                boolean isTerm = false;
                JSONArray jsonArray = data.getJSONArray(CustomerManagementEnum.PHONE.getAttr());
                if (Objects.nonNull(jsonArray)) {
                    for (Object obj : jsonArray) {
                        JSONObject json = (JSONObject) obj;
                        if (Objects.equals(json.getString("text_2"), customerCheckRepeatDTO.getNameLike())) {
                            isTerm = true;
                            break;
                        }
                    }
                }
                if (isTerm) {
                    list.add(0, customerCheckRepeatPojo);
                } else {
                    list.add(customerCheckRepeatPojo);
                }
            }
            if (list.size() == 11) {
                //沙雕睿智操作
                list.remove(10);
                break;
            } else if (list.size() == 10) {
                break;
            }
        }
        CustomerCheckRepeatVO customerCheckRepeatVO = new CustomerCheckRepeatVO();
        customerCheckRepeatVO.setList(list);
        customerCheckRepeatVO.setHeadList(getCustomerCheckRepeatHead());
        return customerCheckRepeatVO;
    }

    @Override
    public ClueCheckRepeatVO clueCheckRepeat(CustomerCheckRepeatDTO customerCheckRepeatDTO) throws XbbException {
        String corpid = customerCheckRepeatDTO.getCorpid();
        String userId = customerCheckRepeatDTO.getUserId();
        // 获取当前用户的权限
        UserVO loginUser = customerCheckRepeatDTO.getLoginUser();
        Set<String> permSet = loginUser.getPermSet();
        boolean isOpenWorkflow = commonHelp.isOpenWorkFlow(corpid);
        customerCheckRepeatDTO.setIsOpenWorkflow(isOpenWorkflow);
        XbbAggregatedPage<PaasFormDataEntityExt> esEntities = clueService.getDuplicateClue(customerCheckRepeatDTO);
        List<ClueCheckRepeatPojo> list = new ArrayList<>();
        Map<String, String> clueStatusMap = ClueStatusEnum.getCodeAndNameMap();
        Map<Long, String> formName = paasFormService.getNameMap(corpid, XbbRefTypeEnum.CLUE.getCode());
        List<Long> clueIdIn = new ArrayList<>();
        // 线索-表单映射关系
        Map<Long, Long> clueFormMap = new HashMap<>();
        for (PaasFormDataEntityExt entity : esEntities.getContent()) {
            clueIdIn.add(entity.getDataId());
            clueFormMap.put(entity.getDataId(), entity.getFormId());
        }
        //获取在公海分组中id
        UserAndDepartmentGetDTO userAndDepartmentGetDTO = new UserAndDepartmentGetDTO();
        BeanUtil.copyProperties(customerCheckRepeatDTO, userAndDepartmentGetDTO);
        Map<String, UserEntity> userEntityMap = userHelp.getUserMap(userAndDepartmentGetDTO);
        List<Long> clueIdInGroup = getCustomerIdInGroup(customerCheckRepeatDTO, clueIdIn, clueFormMap);
        Map<Long, List<String>> mainUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, List<String>> coUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        userTeamService.getUserIdMap(clueIdIn, corpid, XbbRefTypeEnum.CLUE.getCode(), false, mainUserMap, coUserMap);
        // 这里海镔留下了一个坑，针对审批中的数据，这里写死只能通过名称查重，即联系方式查重无效（海镔理由是数据库审批数据联系方式查不动）
        // 以上，在客户电话关闭的情况下，审批数据暂时不考虑处理。有利
        List<PaasProcessDataEntity> paasProcessDataEntityList = new ArrayList<>();
        if (!isOpenWorkflow) {
            paasProcessDataEntityList = paasProcessDataModel.getInApprovalDataByLikeCondition(XbbRefTypeEnum.CLUE.getCode(), ClueEnum.COMPANY_NAME.getAttr(), customerCheckRepeatDTO.getNameLike(), corpid, null);
        }
        boolean grabPermission = true;
        if (!permSet.contains(ProPermissionAliasEnum.CLUE_GAIN.getAlias())) {
            grabPermission = false;
        }
        // 查询开启联系电话的表单
        Map<Long, Integer> openPhoneMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("corpid", corpid);
        map.put("del", DelEnum.NORMAL.getDel());
        map.put("saasMark", BasicConstant.ONE);
        map.put("businessType", XbbRefTypeEnum.CLUE.getCode());
        List<PaasFormExplainEntity> paasFormEntityExtList = paasFormExplainModel.list(map);
        for (PaasFormExplainEntity item : paasFormEntityExtList) {
            if (Objects.nonNull(item) && Objects.equals(item.getDel(), DelEnum.NORMAL.getDel())) {
                String explains = item.getExplains();
                if (Objects.nonNull(explains)) {
                    Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(explains, null);
                    if (explainMap != null) {
                        FieldAttrEntity fieldAttrEntity = explainMap.get(ClueEnum.PHONE.getAttr());
                        openPhoneMap.put(item.getFormId(), BasicConstant.ONE);
                        if (Objects.nonNull(fieldAttrEntity) && (Objects.equals(fieldAttrEntity.getVisible(), BasicConstant.ZERO) || Objects.equals(fieldAttrEntity.getIsOpen(), BasicConstant.ZERO))) {
                            // 只要有一个表单模版电话字段不可见，就去除电话字段模糊搜索
                            openPhoneMap.put(item.getFormId(), BasicConstant.ZERO);
                        }
                    }
                }
            }
        }

        for (PaasFormDataEntityExt entity : esEntities.getContent()) {
            // 当是电话查重且该表单电话字段关闭，直接过滤数据
            if (Objects.equals(customerCheckRepeatDTO.getRule(), CheckRepeatRuleEnum.PHONE.getCode()) &&
                    Objects.equals(openPhoneMap.get(entity.getFormId()), BasicConstant.ZERO)) {
                continue;
            }
            JSONObject data = entity.getData();
            ClueCheckRepeatPojo clueCheckRepeatPojo = new ClueCheckRepeatPojo();
            clueCheckRepeatPojo.setId(entity.getDataId());
            clueCheckRepeatPojo.setAddTime(DateTimeUtil.getStringEpochSecond(entity.getAddTime()));
            clueCheckRepeatPojo.setName(data.getString(CustomerManagementEnum.NAME.getAttr()));
            clueCheckRepeatPojo.setPosition(getCluePostion(entity));
            clueCheckRepeatPojo.setClueStatus(clueStatusMap.getOrDefault(data.getString(ClueEnum.CLUE_STATUS.getAttr()), I18nMessageUtil.getMessage(I18nStringConstant.NOT_SET_UP)));
            Boolean grab = true;
            Boolean addTeam = true;
            List<String> mainUserIdList = mainUserMap.getOrDefault(entity.getDataId(), new ArrayList<>());
            List<String> coUserIdList = coUserMap.getOrDefault(entity.getDataId(), new ArrayList<>());
            if (Objects.equals(entity.getDel(), DelEnum.DELETE.getDel())) {
                grab = false;
                addTeam = false;
            } else if (Objects.equals(data.getInteger(ClueEnum.IS_PUBLIC.getAttr()), 1)) {
                addTeam = false;
            } else if (mainUserIdList.contains(userId) || coUserIdList.contains(userId)) {
                grab = false;
                addTeam = false;
            } else {
                grab = false;
            }
            //没有公海分组权限的线索
            if (!clueIdInGroup.contains(entity.getDataId())) {
                grab = false;
                addTeam = false;
            }

            // 判断有无 "查重-加入团队" 权限
            if (!permSet.contains(ProPermissionAliasEnum.CLUE_REPEAT_JOIN_TEAM.getAlias())) {
                addTeam = false;
            }

            // 判断捞取权限
            if (!grabPermission) {
                grab = false;
            }
            if (grab) {
                ButtonPojo buttonPojo = new ButtonPojo();
                buttonPojo.setAttr("grab");
                buttonPojo.setValue(I18nMessageUtil.getMessage(I18nStringConstant.GRAB));
                clueCheckRepeatPojo.setOption(Collections.singletonList(buttonPojo));
                clueCheckRepeatPojo.setIsGrab(true);
            }
            if (addTeam) {
                ButtonPojo buttonPojo = new ButtonPojo();
                buttonPojo.setAttr("addTeam");
                buttonPojo.setValue(I18nMessageUtil.getMessage(WorkOrderPushConstant.WORK_ORDER_TEAM_ADD_TITLE));
                clueCheckRepeatPojo.setOption(Collections.singletonList(buttonPojo));
                clueCheckRepeatPojo.setIsAddTeam(true);
            }
            clueCheckRepeatPojo.setFormName(formName.get(entity.getFormId()));
            StringBuilder stringBuilder = new StringBuilder();
            for (String mainUserId : mainUserIdList) {
                UserEntity userEntity = userEntityMap.get(mainUserId);
                if (Objects.isNull(userEntity)) {
                    continue;
                }
                StringUtil.stringBuilderAppendSuffix(stringBuilder, ",", userEntity.getName());
            }
            clueCheckRepeatPojo.setMainUser(stringBuilder.toString());
            list.add(clueCheckRepeatPojo);
        }
        for (PaasProcessDataEntity entity : paasProcessDataEntityList) {
            JSONObject data = JSONObject.parseObject(entity.getData());
            ClueCheckRepeatPojo clueCheckRepeatPojo = new ClueCheckRepeatPojo();
            clueCheckRepeatPojo.setId(entity.getTaskId());
            clueCheckRepeatPojo.setAddTime(DateTimeUtil.getStringEpochSecond(entity.getAddTime()));
            clueCheckRepeatPojo.setName(data.getString(ClueEnum.COMPANY_NAME.getAttr()));
            clueCheckRepeatPojo.setPosition(I18nMessageUtil.getMessage(I18nStringConstant.APPROVAL_LIST));
            clueCheckRepeatPojo.setClueStatus(clueStatusMap.getOrDefault(data.getString(ClueEnum.CLUE_STATUS.getAttr()), I18nMessageUtil.getMessage(I18nStringConstant.NOT_SET_UP)));
            clueCheckRepeatPojo.setFormName(formName.get(entity.getFormId()));
            UserEntity userEntity = userEntityMap.get(entity.getCreatorId());
            if (Objects.nonNull(userEntity)) {
                clueCheckRepeatPojo.setMainUser(userEntity.getName());
            }
            if (Objects.equals(customerCheckRepeatDTO.getRule(), CheckRepeatRuleEnum.NAME.getCode()) && Objects.equals(customerCheckRepeatDTO.getNameLike(), data.getString(ClueEnum.COMPANY_NAME.getAttr()))) {
                list.add(0, clueCheckRepeatPojo);
            } else {
                boolean isTerm = false;
                JSONArray jsonArray = data.getJSONArray(ClueEnum.PHONE.getAttr());
                if (Objects.nonNull(jsonArray)) {
                    for (Object obj : jsonArray) {
                        JSONObject json = (JSONObject) obj;
                        if (Objects.equals(json.getString("text_2"), customerCheckRepeatDTO.getNameLike())) {
                            isTerm = true;
                            break;
                        }
                    }
                }
                if (isTerm) {
                    list.add(0, clueCheckRepeatPojo);
                } else {
                    list.add(clueCheckRepeatPojo);
                }
            }
            if (list.size() == 11) {
                list.remove(10);
                break;
            } else if (list.size() == 10) {
                break;
            }
        }
        ClueCheckRepeatVO clueCheckRepeatVO = new ClueCheckRepeatVO();
        clueCheckRepeatVO.setList(list);
        clueCheckRepeatVO.setHeadList(getClueCheckRepeatHead());
        return clueCheckRepeatVO;
    }

    @Override
    public List<Long> getCustomerIdInGroup(CustomerCheckRepeatDTO customerCheckRepeatDTO, List<Long> customerIdIn, Map<Long, Long> customerFormMap) throws XbbException {
        if (customerCheckRepeatDTO.getLoginUser().isAdminOrBoss() || customerCheckRepeatDTO.getLoginUser().isMaxDataPermission()) {
            return customerIdIn;
        }
        if (customerIdIn == null || customerIdIn.isEmpty()) {
            return new ArrayList<>();
        }

        //分组相关条件
        //有权限的表单模版
        List<PaasFormEntityExt> paasFormEntityExtList = paasFormService.getEnableCustomerFormList(customerCheckRepeatDTO.getLoginUser());
        List<Long> formIdList = new ArrayList<>();
        for (PaasFormEntityExt paasFormEntityExt : paasFormEntityExtList) {
            formIdList.add(paasFormEntityExt.getId());
        }
        if (formIdList.isEmpty()) {
            return new ArrayList<>();
        }
        List<Long> customerIdInGroup = new ArrayList<>();
        UserEntity userEntity = new UserEntity();
        BeanUtil.copyProperties(customerCheckRepeatDTO.getLoginUser(), userEntity);
        List<PublicGroupEntity> publicGroupEntityList = publicGroupModel.enableListByFormIdList(customerCheckRepeatDTO.getCorpid(), formIdList);
        boolean noPublicGroup = false;
        // 存在启用公海分组的表单id列表
        List<Long> publicGroupFormIdList = new ArrayList<>();
        if (!publicGroupEntityList.isEmpty()) {
            for (PublicGroupEntity publicGroupEntity : publicGroupEntityList) {
                publicGroupFormIdList.add(publicGroupEntity.getFormId());
            }
            publicGroupEntityList = publicGroupService.filterGroupByUser(publicGroupEntityList, userEntity);
        } else {
            noPublicGroup = true;
        }
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword", customerCheckRepeatDTO.getCorpid()));
        boolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
        boolQueryBuilder.filter(termsQuery(FieldTypeEnum.FLOW_STATUS.getAlias(), Arrays.asList(FlowStatusEnum.NOT_NEED_APPROVAL.getType(), FlowStatusEnum.PASS.getType())));
        boolQueryBuilder.filter(termsQuery(FieldTypeEnum.DATAID.getAlias(), customerIdIn));
        IndexTypeEnum indexTypeEnum = indexTypeModel.getIndexType(customerCheckRepeatDTO.getCorpid(), XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());
        if (noPublicGroup) {
            //关闭所有公海分组
        } else if (publicGroupEntityList.isEmpty()) {
            boolQueryBuilder.filter(termQuery(FieldTypeEnum.DATAID.getAlias(), -1));
        } else {
            for (PublicGroupEntity entity : publicGroupEntityList) {
                BoolQueryBuilder innerBoolQueryBuilder = boolQuery();
                List<ConditionsEntityExt> conditionsEntityExtList = entity.getJsonData().toJavaList(ConditionsEntityExt.class);
                // 业务类型
                EsUtil.parseCondition(innerBoolQueryBuilder, conditionsEntityExtList, "", customerCheckRepeatDTO.getCorpid(), XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
                innerBoolQueryBuilder.filter(termQuery("formId", entity.getFormId()));
                boolQueryBuilder.should(innerBoolQueryBuilder);
            }
            boolQueryBuilder.minimumShouldMatch(MINI_MUM_SHOULD_MATCH);
        }
        List<PaasFormDataEntityExt> paasFormDataEntityExtList = esHelper.findByScroll(indexTypeEnum, boolQueryBuilder, PaasFormDataEntityExt.class, Collections.singletonList(FieldTypeEnum.DATAID.getAlias()));
        for (PaasFormDataEntityExt entityExt : paasFormDataEntityExtList) {
            customerIdInGroup.add(entityExt.getDataId());
        }
        if (noPublicGroup) {
            return customerIdInGroup;
        }
        // 当有公海分组的时候，需要把错误过滤掉的客户id加回来
        for (Long customerId : customerIdIn) {
            Long formId = customerFormMap.get(customerId);
            if (!publicGroupFormIdList.contains(formId) && !customerIdInGroup.contains(customerId)) {
                // 当前客户所在表单模板无公海分组，则没有限制可以抢
                customerIdInGroup.add(customerId);
            }
        }
        return customerIdInGroup;
    }

    private List<JSONObject> getCustomerCheckRepeatHead() {
        return CustomerManagementEnum.getCheckRepeatHead();
    }

    private List<JSONObject> getClueCheckRepeatHead() {
        return ClueEnum.getCheckRepeatHead();
    }

    /**
     * 获取客户位置
     *
     * @param entity
     * @return
     */
    @Override
    public String getCustomerPostion(PaasFormDataEntityExt entity) {
        if (entity.getDel() == 1) {
            return XbbRefTypeEnum.CUSTOMER_RECYCLE.getName();
        }
        if (Objects.equals(entity.getFlowStatus(), FlowStatusEnum.APPROVAL_PENDING.getType()) || Objects.equals(entity.getFlowStatus(), FlowStatusEnum.IN_APPROVAL.getType())) {
            return I18nMessageUtil.getMessage(I18nStringConstant.APPROVAL_LIST);
        }
        if (Objects.equals(entity.getData().getInteger(CustomerManagementEnum.IS_PUBLIC.getAttr()), 1)) {
            return XbbRefTypeEnum.CUSTOMER_PUBLIC.getName();
        }
        return I18nMessageUtil.getMessage(I18nStringConstant.CUSTOMER_LIST);
    }

    /**
     * 获取线索位置
     *
     * @param entity
     * @return
     */
    private String getCluePostion(PaasFormDataEntityExt entity) {
        if (entity.getDel() == 1) {
            return XbbRefTypeEnum.CLUE_RECYCLE.getName();
        }
        if (Objects.equals(entity.getFlowStatus(), FlowStatusEnum.APPROVAL_PENDING.getType()) || Objects.equals(entity.getFlowStatus(), FlowStatusEnum.IN_APPROVAL.getType())) {
            return I18nMessageUtil.getMessage(I18nStringConstant.APPROVAL_LIST);
        }
        if (Objects.equals(entity.getData().getInteger(ClueEnum.IS_PUBLIC.getAttr()), 1)) {
            return XbbRefTypeEnum.CLUE_PUBLIC.getName();
        }
        return I18nMessageUtil.getMessage(I18nStringConstant.CLUE_LIST);
    }

}